﻿using Loong.Admin.Permissions;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;

namespace Loong.Admin.Users
{
    public class UserAppService : AdminAppService, IUserAppService
    {
        private readonly UserManager _userManager;
        private readonly IRepository<User, Guid> _userRepository;

        public UserAppService(UserManager userManager, IRepository<User, Guid> userRepository)
        {
            _userManager = userManager;
            _userRepository = userRepository;
        }

        [Authorize(AdminPermissions.Users.Default)]
        public async Task<UserDto> GetAsync(Guid id)
        {
            var user = await _userRepository.GetAsync(id);

            return ObjectMapper.Map<User, UserDto>(user);
        }

        public async Task<PagedResultDto<UserDto>> GetListAsync(GetUsersInput input)
        {
            var upperFilter = input.Filter?.ToUpperInvariant();

            var query = await _userRepository.GetQueryableAsync();
            query.WhereIf(
                !input.Filter.IsNullOrWhiteSpace(),
                u =>
                    u.NormalizedUserName.Contains(upperFilter!) ||
                    u.NormalizedEmail.Contains(upperFilter!) ||
                    (u.Name != null && u.Name.Contains(input.Filter!)) ||
                    (u.Surname != null && u.Surname.Contains(input.Filter!)) ||
                    (u.PhoneNumber != null && u.PhoneNumber.Contains(input.Filter!)));

            var count = await AsyncExecuter.LongCountAsync(query);

            var list = await AsyncExecuter.ToListAsync(query.OrderBy(u => u.UserName).PageBy(input));

            return new PagedResultDto<UserDto>()
            {
                TotalCount = count,
                Items = ObjectMapper.Map<List<User>, List<UserDto>>(list)
            };
        }

        public async Task<UserDto> CreateAsync(CreateUserDto input)
        {
            var user = new User(GuidGenerator.Create(), input.UserName, input.Email);
            user.SetPhoneNumber(input.PhoneNumber);
            user.SetLockoutEnabled(input.LockoutEnabled);
            user.Name = input.Name;
            user.Surname = input.Surname;
            user.SetIsActive(input.IsActive);

            await _userManager.CreateAsync(user, input.Password);

            await _userRepository.InsertAsync(user);

            return ObjectMapper.Map<User, UserDto>(user);
        }
    }
}
